package Day5;

import org.junit.Test;

import java.util.*;

/**
 * @author ：Yan Guang
 * @date ：Created in 2020/4/30 17:34
 * @description：----
 * -Collection接口:单列集合，用来存储一 个一一个的对象
 * /----Set接心:存储无序的、不可重复的数据 -->高中讲的“集合”
 * ----HashSet:是set接口的主要实现类(链表跟顺序表的结合)
 * Set:存储无序的、不可重复的数据
 * 以HashSet为例说明:
 * 1.无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加，而是根据顺序表
 * 2.不可重复性:保证添加的元素按照equals()判断时，不能返回true.对象要想相同，需要重写equls跟hashcode
 * -------------------------------------------------
 * 二、添加元素的过程:以HashSet 为例:
 * 我们向HashSet中添加元素,首先调用元素a所在类的hashCode()方法，计算元素a的哈希 值，
 * 此哈希值接者通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置)，判断
 * 数组此位置上是否已经有元素:
 * 如果此位置上没有其他元素，则元素a添加成功。
 * 如果此位置上有其他元b(或以链表形式存在的多个元素)，则比较元素a与元素b的hash值:
 * 如果hash值不相同，则元素a添加成功。
 * 如果hash值相同，进而需要调用元素a所在类的equlas()方法:先比hashcode再equals
 * equals()返回true,元素a添加失败
 * equals()返回false,则元素a添加成功。
 * 对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储。
 * jdk 7 :元素a放到数组中，指向原来的元素。
 * jdk 8 :原来的元素在数组中，指向元素d
 * 总结一句话：七上八下
 * ----------------------------------------
 * LinkedHashSet：是HashSet的子类，让他看起来有序
 * //LinkedHashSet的使用
 * //LinkedHashSet作为HashSet的子类，在添加数据的同时，每个数据还维护了两个引用，记之前面
 * //一个数据和后一个数据。
 * //优点:对于频繁的遍历操作，LinkedHashSet 效率高HashSet
 * -----------------------------------------------------------
 * TreeSet：可以按照添加对象的指定属性进行排序
 * 向TreeSet中添加的数据，要求是相同类的对象。
 * 自然排序中，比较两个对象是否相同的标准为: compareTo() 返回e.不再是equals().
 * 定制排序中，比较两个对象是否相同的标准为: compare() 返回e.不再是equals().
 */
class Person implements Comparable{//自定义排序
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return name.equals(person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    @Override
    public int compareTo(Object o) {//重新的compare方法，按照字母顺序去排列
       if (o instanceof Person){
           Person person=(Person)o;
           return this.name.compareTo(person.name);
       }else {
           throw new RuntimeException("输入的不匹配");
       }
    }
}

public class SetTest {
    @Test
            public void test3(){

        Set set = new HashSet();//随机性在一开始存放在顺序表中,就是一开始是随机放进数组中的
        set.add(456);
        set.add(567);
        set.add(new Person("LIUChengHao"));
        set.add(new Person("YanGuang"));//不允许重复
        set.add(new Person("YanGuang"));
        System.out.println(set);


        Set set1 = new LinkedHashSet();//随机性在一开始存放在顺序表中,但是有(一定)的顺序（进去的时候也有两个指针）
        set1.add(456);
        set1.add(567);
        set1.add(new Person("LIUChengHao"));
        set1.add(new Person("YanGuang"));//不允许重复
        set1.add(new Person("YanGuang"));
        System.out.println(set1);

        Set set2=new TreeSet();//自然排序
        set2.add(new Person("LIUChengHao"));
        set2.add(new Person("YanGuang"));
        set2.add(new Person("AiuXiaoGang"));
        System.out.println(set2);
    }

    @Test
    public void test4(){
        System.out.println("测试单元测试方法");
    }
}
